package pl.edu.mimuw.irs.core.model.petrinet;

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;

import pl.edu.mimuw.irs.core.global.IDManager;
import pl.edu.mimuw.irs.core.model.design.exception.InternalDesignException;
import pl.edu.mimuw.irs.core.model.design.exception.InternalDesignException.DesignCause;

/**
 * @author Jakub Rauch
 * Created on: 2009-05-07
 */
public abstract class Element implements IElement {

	private static final long serialVersionUID = 241655908565955213L;
	
	// *** Attributes

	// The whole net
	private Net net;
	private String id;
	private IDManager idManager;
	private transient PropertyChangeSupport listeners;
	public Net getNet() {
		return net;
	}
	public void setNet(Net net) {
		this.net = net;
	}

	@Override
	public String getId() {
		if (id == null) setId(idManager.getNewId());
		return id;
	}
	@Override
	public void setId(String id) {
		getIdManager().changeId(this.id, id);
		this.id = id;
	}
	@Override
	public IDManager getIdManager() {
		return idManager;
	}
	@Override
	public void setIdManager(IDManager idManager) {
		if (this.idManager == idManager) return;
		/* Remove from from net and old manager if attached. */
		Net net = getNet();
		if (this.idManager == null) {
			if (net != null) throw new InternalDesignException(DesignCause.NET_MEMBER_WITHOUT_ID_MANAGER, this);
		} else {
			if (net != null) net.removeElement(this);
			this.setId(null);
		}
		/* Add to new manager and add to net with new id */
		this.idManager = idManager;
		if (net != null) net.addElement(this);
	}
	public PropertyChangeSupport getListeners() {
		if (listeners == null) listeners = new PropertyChangeSupport(this);
		return listeners;
	}
	
	// *** Methods
	
	@Override
	public void addPropertyChangeListener(PropertyChangeListener listener) {
		getListeners().addPropertyChangeListener(listener);
	}

	@Override
	public void addPropertyChangeListener(String property, PropertyChangeListener listener) {
		getListeners().addPropertyChangeListener(property, listener);
	}
	
	@Override
	public void removePropertyChangeListener(PropertyChangeListener listener) {
		getListeners().removePropertyChangeListener(listener);
	}
	
	@Override
	public void removePropertyChangeListener(String property, PropertyChangeListener listener) {
		getListeners().removePropertyChangeListener(property, listener);
	}

	@Override
	protected void finalize() throws Throwable {
		getIdManager().remove(getId());
		super.finalize();
	}

	@Override
	public String toString() {
		return getId();
	}
}
